perm filename UPDATE.TEX[CLS,LSP] blob
sn#847187 filedate 1987-10-19 generic text, type C, neo UTF8
COMMENT ā VALID 00004 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 \begincom{update-instance-structure}\ftype{Generic Function}
C00009 00003 \begincom{change-class}\ftype{Function}
C00016 00004 \begincom{make-instances-obsolete}\ftype{Generic Function}
C00019 ENDMK
Cā;
\begincom{update-instance-structure}\ftype{Generic Function}
\label Purpose:
The generic function {\bf update-instance-structure} is not intended to
called by programmers. Programmers are expected to write methods for it.
The generic function {\bf update-instance-structure} is called only by
{\bf change-class}.
\label Syntax:
\Defgen {update-instance-structure}{class added-slots deleted-slots property-list}
\label Arguments:
When {\bf make-instances-obsolete} is invoked or when a class has been
redefined and an instance is being updated, a property list is created
that captures the slot names and values of all the slots with values in
the original instance. The structure of the instance is transformed so
that it conforms to the current class definition; all the slots of this
transformed instance are uninitialized. This transformed instance, a list
of the new slots added to the instance, a list of the old slots deleted
from the instance, and the property list containing the slot names and
values for the obsolete instance are the arguments to {\bf
update-instance-structure}.
\label Values:
The value returned by {\bf update-instance-structure} is ignored.
\label Examples:
\screen!
(defclass position () ())
(defclass x-y-position (position)
((x :initform 0 :accessor position-x)
(y :initform 0 :accessor :position-y)))
;;; It turns out we use polar co-ordinates more than Cartesian
;;; co-ordinates, so we alter the representation and add some
;;; new accessor methods.
(defmethod update-instance-structure
((pos x-y-position) added deleted plist)
;; Copy the position information from old to new to make new
;; be a rho-theta-position at the same position as old.
(let ((x (getf plist 'x))
(y (getf plist 'y)))
(setf (position-rho new) (atan y x)
(position-theta new) (sqrt (+ (* x x) (* y y))))))
(defclass x-y-position (position)
((rho :initform 0 :accessor position-rho)
(theta :initform 0 :accessor positiontheta)))
;;; All instances of the old x-y-position class will be updated
;;; automatically.
;;; We give the new representation the look and feel of the old one
(defmethod position-x ((pos x-y-position))
(with-slots pos (rho theta) (* rho (cos theta))))
(defmethod (setf position-x) (new-x (pos x-y-position))
(with-slots pos (rho theta)
(let ((y (position-y pos)))
(setq rho (atan y new-x)
theta (sqrt (+ (* new-x new-x) (* y y))))
new-x)))
(defmethod position-y ((pos x-y-position))
(with-slots pos (rho theta) (* rho (sin theta))))
(defmethod (setf position-y) (new-y (pos x-y-position))
(with-slots pos (rho theta)
(let ((x (position-x pos)))
(setq rho (atan new-y x)
theta (sqrt (+ (* x x) (* new-y new-y))))
new-y)))
\endscreen!
\label Remarks:
The default method for {\bf update-instance-structure} does the following:
\beginlist
\item{\bull} For each local slot in current class definition, if its
slot name appears in the property list, the value corresponding to the
slot name in the property list is stored in the local slot. Shared slots
are not changed.
\item{\bull} For any slot in the instance that is still uninitialized and
for which there is an {\bf :initform} form in the current class
definition, the {\bf :initform} form is evaluated and the value stored in
the local slot.
\endlist
The generic function {\bf update-instance-structure} uses standard method
combination; thus {\bf :before}, {\bf :after}, {\bf :around}, and
unqualified methods are allowed.
\label See Also:
``Redefining Classes''
{\bf make-instances-obsolete}
\endcom
\begincom{change-class}\ftype{Function}
\label Purpose:
The function {\bf change-class} changes the class of an instance to a
new class. It destructively modifies and returns the instance. The
values of local slots held in common between the old and new class are
preserved in the new instance. The other slots are initialized as
described in the section ``Changing Classes.''
\label Syntax:
\Defun {change-class} {instance new-class}
\label Arguments:
The {\it instance\/} argument is a Lisp object, although
not all objects are required to allow {\bf change-class}.
The {\it new-class\/} argument is a class object or a symbol that names
a class.
\label Values:
The modified instance is returned. The result of {\bf change-class}
is {\bf eq} to the {\it instance} argument.
\label Examples:
\screen!
(defclass position () ())
(defclass x-y-position (position)
((x :initform 0)
(y :initform 0)))
(defclass rho-theta-position (position)
((rho :initform 0)
(theta :initform 0)))
(defmethod class-changed ((old x-y-position)
(new rho-theta-position))
;; Copy the position information from old to new to make new
;; be a rho-theta-position at the same position as old.
(let ((x (position-x old))
(y (position-y old)))
(setf (position-rho new) (atan y x)
(position-theta new) (sqrt (+ (* x x) (* y y))))))
;;; At this point an instance of the class x-y-position can be
;;; changed to be an instance of the class rho-theta-position using
;;; change-class:
(setq p1 (make-instance 'x-y-position :x 2 :y 0))
(change-class p1 'rho-theta-position)
;;; The result is that the instance bound to p1 is now an instance of
;;; the class rho-theta-position. The method for class-changed
;;; performed the initializion of the rho and theta slots based
;;; on the value of the x and y slots, which were maintained by
;;; the old instance.
\endscreen!
\label Remarks:
The \OS\ requires {\bf change-class} to apply in only the following case:
let $C\sub 1$ and $C\sub 2$ be classes that are defined by {\bf
defclass} without using the {\bf :metaclass} option in either case; let
$X$ be an instance of $C\sub 1$. Then, the class of $X$ can be changed
from $C\sub 1$ to $C\sub 2$. Both before and after the call to {\bf
change-class}, the metaclass of $X$ is the default metaclass, namely
{\bf standard-class}.
Implementors can choose to support {\bf change-class} in additional
cases. For example, this standard does not require that
{\bf change-class} be able to accept an instance of a standard type class
as its first argument or a standard type class as its second argument;
however, it is valid for an implementation to support this for some
standard type classes.
If {\bf change-class} is applied to arguments that are not supported by
the implementation, an error is signaled.
After completing all other actions, {\bf change-class} invokes the generic
function {\bf class-changed}. The generic function {\bf class-changed}
can be used to reinitialize slots.
The function {\bf change-class} has several semantic difficulties.
First, it performs a destructive operation that can be invoked within a
method on an instance that was used to select that method. When multiple
methods are involved because methods are being combined, the problem
could be compounded. Second, some implementations might use compiler
optimizations of slot access and when the class of an instance is
changed, the assumptions the compiler made might be violated.
This implies that an application programmer must not use {\bf
change-class} inside a method if any methods for that generic function
access any slots.
\eject
\label See Also:
``Redefining Classes''
{\bf class-changed}
\endcom
\begincom{make-instances-obsolete}\ftype{Generic Function}
\label Purposes:
The generic function {\bf make-instances-obsolete} is invoked automatically by
the system after {\bf defclass} has been used to redefine an existing
class. It can also be explicitly invoked by the user.
It causes the generic function
{\bf update-obsolete-instances} to be invoked.
\label Syntax:
\Defgen {make-instances-obsolete} {old-class}
The {\it old-class\/} argument is a class object or a symbol that names
the class to be redefined.
\label Values:
The modified class is returned. The result of {\bf make-instances-obsolete}
is {\bf eq} to the {\it old-class} argument.
\label Examples:
See the example under {\bf update-instance-structure}.
\label Remarks:
The generic function {\bf make-instances-obsolete} is invoked only on
classes that are instances of {\bf standard-class}.
\label See Also:
{\bf update-instance-structure}
``Redefining Classes''
\endcom